/**
 * 
 * The bomb class represents a bomb on the field.
 * 
 * Author: Matthias Van Eeghem <matthias@van-eeghem.com>
 * All rights reserved.
 * 
 */

package com.bomberman.bomb;

import com.bomberman.core.Element;
import com.bomberman.core.Game;
import com.bomberman.player.Player;
import com.bomberman.player.PlayerManager;

public class Bomb extends Element
{
	/**
	 * Current bomb tick state.
	 */
	public enum BombState
	{
		JUST_CREATED,
		TICK_ONE,
		TICK_TWO,
		TICK_THREE,
		TICK_FOUR,
		TICK_FIVE,
		TICK_SIX,
		TICK_SEVEN,
		TICK_EIGHT,
		TICK_NINE,
		TICK_TEN,
		TICK_ELEVEN,
		TICK_TWELVE,
		HAS_TO_EXPLODE
	}
	
	/**
	 * Holds the current bomb state
	 */
	private BombState bombState = BombState.JUST_CREATED;
	/**
	 * This variable holds the owner of the bomb, ergo the player who put the bomb in its location.
	 */
	private Player ownerOfTheBomb;

	/**
	 * The Bomb constructor, initialises all variables.
	 * 
	 * @param row The row the bomb should be located on
	 * @param column The column the bomb should be located on
	 */
	public Bomb(Player owner, int row, int column)
	{
		super(row, column, Element.ElementType.TYPE_BOMB);
		
		this.ownerOfTheBomb = owner;
	}
	
	/**
	 * This method returns the bomb's owner
	 * 
	 * @return The player object that owns the bomb
	 */
	public Player getBombOwner()
	{
		return ownerOfTheBomb;
	}
	
	/**
	 * Increments the bomb state
	 */
	public void incrementState()
	{
		bombState = BombState.values()[bombState.ordinal() + 1];
	}
	
	/**
	 * Returns the bombstate for this bomb.
	 * 
	 * @return The bombstate
	 */
	public BombState getState()
	{
		return bombState;
	}
	
	/**
	 * Returns true if the player is at that position.
	 * 
	 * @param firstColumn First column of the player
	 * @param secondColumn (Potentially invalid) second column of the player
	 * @param firstRow First row of the player
	 * @param secondRow (Potentially invalid) second row of the player
	 * @param row The row where we want to check if the player is there
	 * @param column The column where we want to check if the player is there
	 * @return
	 */
	private boolean isPlayerAtPosition(int firstColumn, int secondColumn, int firstRow, int secondRow, int row, int column)
	{
		// The player is at the exact row and column
		if(firstRow == row && firstColumn == column)
			return true;
		
		// The first row is a match and the column matches the secondColumn
		if(firstRow == row && (secondRow != Game.INVALID_ROW_ID && secondColumn == column))
			return true;
		
		// The second row is a match and the column matches the firstColumn
		if((secondRow != Game.INVALID_ROW_ID && secondRow == row) && firstColumn == column)
			return true;
		
		// secondRow matches the first row and the second column is the column
		if((secondRow != Game.INVALID_ROW_ID && secondRow == row) && (secondColumn != Game.INVALID_COLUMN_ID && secondColumn == column))
			return true;
		
		// The player isn't at the position
		return false;
	}
	
	/**
	 * This method kills all players in a range of the bomb.
	 */
	public void killPlayersInRange()
	{
		if(!Game.gameOver)
		{
			// Draw all players
			for (Player player : PlayerManager.getPlayerList())
			{
				// Get the column or columns the player is located on
				int firstColumn = player.getColumns().get(0);
				int secondColumn = (player.getColumns().size() > 1) ? player.getColumns().get(1) : Game.INVALID_COLUMN_ID;
				
				// Get the row or rows the player is located on
				int firstRow = player.getRows().get(0);
				int secondRow = (player.getRows().size() > 1) ? player.getRows().get(1) : Game.INVALID_COLUMN_ID;
				
				// Get the position of the bomb
				int bombRow = getRow();
				int bombColumn = getColumn();
				
				// By default, the bomb "touches" 5 locations when exploding,
				// The actual position where the bomb exploded, and the brick
				// on the left, the one on the right, the one above the current one
				// and the one below that one.
				if(isPlayerAtPosition(firstColumn, secondColumn, firstRow, secondRow, bombRow, bombColumn) ||
				   isPlayerAtPosition(firstColumn, secondColumn, firstRow, secondRow, bombRow + 1, bombColumn) ||
				   isPlayerAtPosition(firstColumn, secondColumn, firstRow, secondRow, bombRow - 1, bombColumn) ||
				   isPlayerAtPosition(firstColumn, secondColumn, firstRow, secondRow, bombRow, bombColumn + 1) ||
				   isPlayerAtPosition(firstColumn, secondColumn, firstRow, secondRow, bombRow, bombColumn - 1))
				{
					// Game over for this player
					Game.gameOver = true;
					System.out.printf("%s was killed by %s\n", player.getName(), this.getBombOwner().getName());
					return;
				}
			}
		}
	}
}
